<?php
defined('IN_CMS') or die('Direct access to Script restricted.');

class User extends Common
{
	private $arr_user;			// Массив с информацией о посетителе
	private $uin;				// Уникальный идентификатор

	/**
	 * Конструктор класса
	 */
	public function __construct()
	{
		$user_id = isset($_SESSION['user_id']) && (int)$_SESSION['user_id'] > 0 ? (int)$_SESSION['user_id'] : 0;
		$token = isset($_COOKIE['token']) && !empty($_COOKIE['token']) ? $_COOKIE['token'] : false;

		if ($user_id == 0 && $token)
		{
			// Авторизовать посетителя автоматически при его заходе на сайт
			$this->autoUserLogin($token);
		}
		else
		{
			// Установим информацию о посетителе сайта
			$this->setUserInfo();
		}
	}

	/**
	 * Деструктор класса
	 */
	public function __destruct()
	{

	}

	/**
	 * ValidateUser()
	 *
	 * @param	string	$username
	 * @param	string	$password
	 * @return	int
	 */
	public function ValidateUser($username, $password)
	{
		$user_id = false;
		
		// Получим пароль в том виде, в каком он хранится в БД
		$password = self::$obj_functions->super_crypt($username, $password, SALT);

		$sql = "SELECT 
					user_id	
				FROM 
					" . TABLE_PREFIX . "users 
				WHERE 
					username = " . self::$obj_functions->toMySQL($username, true) . "
					AND
					password = " . self::$obj_functions->toMySQL($password, true) . "
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if ( self::$obj_db->sql_numrows($result) > 0 )
		{
			// Юзер с указанным именем и паролем найден
			$row = self::$obj_db->sql_fetchrow($result);
			$user_id = (int)$row['user_id'];

			// Обнуляем кол-во неудачных попыток входа
			$this->ResetLoginAttempts($username);
		}
		else
		{
			// Увеличиваем кол-во неудачных попыток входа на 1
			$this->IncreaseLoginAttempts($username);
		}

		self::$obj_db->sql_freeresult($result);
		unset($sql, $result, $row, $username, $password);
		
		return $user_id;
	}

	/**
	 * Обнуляем кол-во неудачных попыток входа
	 * 
	 * @param	string	$username
	 * @return	void
	 */
	public function ResetLoginAttempts($username)
	{
		$sql = "UPDATE
					" . TABLE_PREFIX . "users
				SET
					login_attempts = 0
				WHERE
					username = " . self::$obj_functions->toMySQL($username, true) . "
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);

		self::$obj_db->sql_freeresult($result);
		unset($sql, $result, $row, $username);
	}

	/**
	 * Увеличиваем кол-во неудачных попыток входа на 1
	 *
	 * @param	string	$username
	 * @return	void
	 */
	public function IncreaseLoginAttempts($username)
	{
		$sql = "UPDATE
					" . TABLE_PREFIX . "users
				SET
					login_attempts = login_attempts + 1
				WHERE
					username = " . self::$obj_functions->toMySQL($username, true) . "
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);

		self::$obj_db->sql_freeresult($result);
		unset($sql, $result, $row, $username);
	}

	/**
	 * Баним юзера
	 * 
	 * @param	int		$user_id
	 * @param	string	$ban_start
	 * @param	string	$ban_end
	 * @param	string	$ban_reason
	 * @param	string	$ban_give_reason
	 */
	public function BanUser($user_id, $ban_start, $ban_end, $ban_reason, $ban_give_reason)
	{
		$date_start = self::$obj_functions->toMySQL(date('Y-m-d H:i:s', strtotime($ban_start)));
		$date_end = '0000-00-00 00:00:00';
		if ($ban_end != '')
		{
			$date_end = self::$obj_functions->toMySQL(date('Y-m-d H:i:s', strtotime($ban_end)));
		}

		$sql = "INSERT INTO " . TABLE_PREFIX . "users_black_list
				(
					user_id,
					ban_start,
					ban_end,
					ban_reason,
					ban_give_reason 
				)
				VALUES
				(
					" . (int)$user_id . ",
					" . $date_start . ",
					" . $date_end . ",
					" . self::$obj_functions->toMySQL($ban_reason, true) . ",
					" . self::$obj_functions->toMySQL($ban_give_reason, true) . "
				)
				ON DUPLICATE KEY UPDATE
					ban_start = " . $date_start . ",
					ban_end = " . $date_end . ",
					ban_reason = " . self::$obj_functions->toMySQL($ban_reason, true) . ",
					ban_give_reason = " . self::$obj_functions->toMySQL($ban_give_reason, true) . "";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);

		self::$obj_db->sql_freeresult($result);
		unset($sql, $result, $user_id, $ban_start, $ban_end, $ban_reason, $ban_give_reason, $date_start, $date_end);
	}

	/**
	 * CheckBan()
	 *
	 * @param	string	$user_id
	 * @return	array
	 */
	public function CheckBan($user_id)
	{
		$ban = array();
		
		//
		$sql = "SELECT
					user_id,
					ban_start,
					ban_end,
					ban_reason,
					ban_give_reason
				FROM
					" . TABLE_PREFIX . "users_black_list
				WHERE
					user_id = " . (int)$user_id . "
					AND
					ban_start <= NOW()
					AND
					(
					ban_end = '0000-00-00 00:00:00'
					OR
					ban_end > NOW()
					)
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if ( self::$obj_db->sql_numrows($result) > 0 )
		{
			$row = self::$obj_db->sql_fetchrow($result);
			
			$ban['user_id'] = (int)$row['user_id'];
			$ban['ban_start'] = $row['ban_start'];
			$ban['ban_end'] = $row['ban_end'] == '0000-00-00 00:00:00' ? '' : $row['ban_end'];
			$ban['ban_reason'] = self::$obj_functions->toHTML($row['ban_reason']);
			$ban['ban_give_reason'] = self::$obj_functions->toHTML($row['ban_give_reason']);
		}

		self::$obj_db->sql_freeresult($result);
		unset($sql, $result, $row, $user_id);

		if (count($ban) == 0)
		{
			return false;
		}

		return $ban;
	}

	/**
	 * Автоматический вход для юзера
	 *
	 * @param	string	$token
	 * @return	bool
	 */
	public function autoUserLogin($token)
	{
		unset($this->arr_user, $this->uin);
		$_SESSION['user_id'] = '';
		$_SESSION['arr_user'] = '';

		// Найдем пользователя, у которого будет соответствующий "token"
		$sql = "SELECT
					user_id
				FROM
					" . TABLE_PREFIX . "users
				WHERE
					token = " . self::$obj_functions->toMySQL($token, true) . "
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if ( self::$obj_db->sql_numrows($result) > 0 )
		{
			$row = self::$obj_db->sql_fetchrow($result);
			$user_id = (int)$row['user_id'];

			if ($ban = $this->CheckBan($user_id))
			{
				$user_id = 0;
			}
		}
		self::$obj_db->sql_freeresult($result);

		if ($user_id > 0)
		{
			$_SESSION['user_id'] = $user_id;

			// Обновим информацию о пользователе
			$this->setUserInfo();

			// Соберем мусор
			unset($token, $user_id, $sql, $result, $row);
			return true;
		}

		// Соберем мусор
		unset($token, $user_id, $sql, $result, $row, $ban);
		return false;
	}

	/**
	 * UserLogin()
	 *
	 * @param	int		$user_id
	 * @param	string	$username
	 * @param	string	$password
	 * @param	bool	$remember
	 * @return	void
	 */
	public function UserLogin($user_id, $username, $password, $remember)
	{
		unset($this->arr_user, $this->uin);
		$_SESSION['user_id'] = '';
		$_SESSION['arr_user'] = '';
		
		if ($user_id > 0)
		{
			$_SESSION['user_id'] = $user_id;

			// Если юзер пометил чекбокс "запомнить меня на этом компьютере",
			// сохраним в кукисах "token"
			if ($remember)
			{
				$token = md5(time().$username.$password);
				setcookie('token', $token, time() + 3600*24*31, '/');  // 3600 = 1 час; 3600*24*31 = 1 месяц
				// Нужно записать ту же строку token в базу данных, в строку для залогинившегося юзера.
				// Впоследствии мы будем искать по этой строке (когда она придет из куки) нужного пользователя.
				$sql = "UPDATE
							" . TABLE_PREFIX . "users
						SET
							token = " . self::$obj_functions->toMySQL($token, true) . "
						WHERE
							user_id = " . (int)$user_id . "
						LIMIT 1";
				
				//self::$obj_error->showMessage($sql, 3);
				$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
				self::$obj_db->sql_freeresult($result);
			}

			// Получим доп. информацию о юзере
			$this->setUserInfo();
		}

		unset($user_id, $username, $password, $remember, $token, $sql, $result);
	}

	/**
	 * Обработка выхода юзера
	 *
	 * @return	void
	 */
	public function UserLogout()
	{
		unset($this->arr_user, $this->uin);
		$_SESSION['user_id'] = '';
		$_SESSION['arr_user'] = '';
		setcookie('token', '', time()-360000, '/');
		setcookie('UIN', '', time()-360000, '/');
	}

	/**
	 * Обновляет дату и время последнего визита пользователя на страницу
	 *
	 */
	public function UpdateLastVisit()
	{
		if ( $this->getUserID() > 0 )
		{
			$sql = "UPDATE
						" . TABLE_PREFIX . "users 
					SET
						lastvisit_date = " . self::$obj_functions->toMySQL(date("Y-m-d H:i:s")) . ",
						lastvisit_ip = " . self::$obj_functions->toMySQL($_SERVER['REMOTE_ADDR'], true) . ",
						uin = " . self::$obj_functions->toMySQL($this->uin, true) . "
					WHERE
						user_id = " . (int)$this->getUserID() . "
					LIMIT 1";

			//self::$obj_error->showMessage($sql, 3);
			$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
			self::$obj_db->sql_freeresult($result);
		}
	}

	/**
	 * Обновляет пароль юзера и обнуляет код сброса пароля
	 * 
	 * @param	int		$user_id
	 * @param	string	$password
	 */
	public function UpdatePassword($user_id, $password)
	{
		//
		$sql = "UPDATE
					" . TABLE_PREFIX . "users
				SET
					password = " . self::$obj_functions->toMySQL($password) . ",
					password_reset_code = '' 
				WHERE 
					user_id = " . (int)$user_id . "
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		
		self::$obj_db->sql_freeresult($result);
		unset($user_id, $password, $sql, $result);
	}
	
	/**
	 * setUserInfo()
	 *
	 * @return	void
	 */
	private function setUserInfo()
	{
		// Сохраним куки с уникальным идентификатором
		// В дальнейшем используем для идентификации незарегистрированных посетителей
		// (например при добавлении товаров в корзину покупок)
		unset($this->uin);
		if (!isset($_COOKIE['UIN']) || $_COOKIE['UIN'] == '')
		{
			$this->uin = self::$obj_functions->UIN();
			setcookie("UIN", $this->uin, time()+3600*24*31, '/');  // 3600 = 1 час; 3600*24*31 = 1 месяц
		}
		else
		{
			setcookie("UIN", $_COOKIE['UIN'], time()+3600*24*31, '/');
			$this->uin = $_COOKIE['UIN'];
		}

		//
		unset($this->arr_user);
		$user_id = isset($_SESSION['user_id']) && (int)$_SESSION['user_id'] > 0 ? (int)$_SESSION['user_id'] : 0;
		if ($user_id > 0)
		{
			if (isset($_SESSION['arr_user']) && !empty($_SESSION['arr_user']))
			{
				// Получим информацию о юзере из сессии
				$this->arr_user = unserialize($_SESSION['arr_user']);
			}
			else
			{
				// Получим информацию о юзере из БД
				$this->arr_user = $this->getUserInfo($user_id);

				// Сохраним массив в сессии
				$_SESSION['arr_user'] = serialize($this->arr_user);
			}

			// Обновим дату последнего посещения
			$this->UpdateLastVisit();
		}
		
		// Обновляем информацию о посетителях "онлайн"
		$this->UpdateUsersOnline();
	}
	
	/**
	 * Обновляем информацию о посетителях "онлайн"
	 * 
	 */
	public function UpdateUsersOnline()
	{
		if ((int)$_SESSION['user_id'] == 0)
		{
			$_SESSION['profile_id'] = 0;
			$_SESSION['profile_code'] = '';
		}
		
		// убираем записи, которые не обновлялись в течении 10 минут:
		$sql = "DELETE FROM 
					" . TABLE_PREFIX . "who_is_online 
				WHERE 
					dt < SUBTIME(NOW(),'0 0:10:0')";
		
		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		
		// Проверяем отмечен ли посетитель как "онлайн"
		$sql = "SELECT 
					count(*) AS qty 
				FROM 
					" . TABLE_PREFIX . "who_is_online 
				WHERE 
					uin = " . self::$obj_functions->toMySQL($this->uin, true) . "";
		
		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if ( self::$obj_db->sql_numrows($result) > 0 )
		{
			$row = self::$obj_db->sql_fetchrow($result);
			if ((int)$row['qty'] > 0)
			{
				// Если пользователь онлайн, просто внести изменения в значение поля "dt"
				//mysql_query("UPDATE tz_who_is_online SET dt=NOW() WHERE ip=".$intIp);
				$sql = "UPDATE 
							" . TABLE_PREFIX . "who_is_online 
						SET 
							dt = NOW(), 
							user_id = " . (int)$_SESSION['user_id'] . ", 
							profile_id = " . (int)$_SESSION['profile_id'] . ", 
							ip = " . self::$obj_functions->toMySQL($_SERVER['REMOTE_ADDR'], true) . " 
						WHERE 
							uin = " . self::$obj_functions->toMySQL($this->uin, true) . "";
			}
			else 
			{
				// Этого пользователя нет в БД
				//mysql_query("	INSERT INTO tz_who_is_online (ip,city,country,countrycode) VALUES (".$intIp.",'".$city."','".$countryName."', '".$countryAbbrev."')");
				$sql = "INSERT INTO " . TABLE_PREFIX . "who_is_online 
						(
							dt, 
							user_id, 
							profile_id, 
							ip, 
							uin 
						) 
						VALUES 
						(
							NOW(), 
							" . (int)$_SESSION['user_id'] . ", 
							" . (int)$_SESSION['profile_id'] . ", 
							" . self::$obj_functions->toMySQL($_SERVER['REMOTE_ADDR'], true) . ", 
							" . self::$obj_functions->toMySQL($this->uin, true) . " 
						)";
			}
			
			//self::$obj_error->showMessage($sql, 3);
			$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($sql, $result, $row);
	}

	/**
	 * Возвращает дополнительную информацию о пользователе
	 * 
	 * @param	int		$user_id
	 * @param	bool	$reload
	 * @return	array
	 */
	public function getUserInfo($user_id, $reload = false)
	{
		if ($user_id == 0)
		{
			// Если не указан ID юзера, то возьмем ID текущего юзера
			$user_id = $this->getUserID();
		}

		if (!$reload && isset($this->arr_user) && count($this->arr_user) > 0 && $user_id == $this->arr_user['user_id'])
		{
			// Если информация о этом юзере уже есть в массиве,
			// нет необходимости в запросе к БД
			return $this->arr_user;
		}
		
		$user = array();
		
		// Получим дополнительную информацию о пользователе
		$sql = "SELECT
					user_id,
					uin,
					username, 
					first_name,
					last_name,
					nickname,
					email,
					avatar,
					lastvisit_date, 
					is_admin 
				FROM
					" . TABLE_PREFIX . "users
				WHERE
					user_id = " . (int)$user_id . "
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if ( self::$obj_db->sql_numrows($result) > 0 )
		{
			$row = self::$obj_db->sql_fetchrow($result);
			$user['user_id'] = (int)$row['user_id'];
			$user['username'] = self::$obj_functions->toHTML($row['username']);
			$user['first_name'] = self::$obj_functions->toHTML($row['first_name']);
			$user['last_name'] = self::$obj_functions->toHTML($row['last_name']);
			$user['nickname'] = self::$obj_functions->toHTML($row['nickname']);
			$user['email'] = self::$obj_functions->toHTML($row['email']);
			$user['avatar'] = self::$obj_functions->toHTML($row['avatar']);
			$user['lastvisit_date'] = $row['lastvisit_date'];
			$user['is_admin'] = (int)$row['is_admin'];
		}

		if ($reload)
		{
			$this->arr_user = $user;
			$_SESSION['arr_user'] = serialize($this->arr_user);
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($user_id, $sql, $result, $row);
		return $user;
	}

	/**
	 * EncryptPassword()
	 *
	 * @param	string	$username
	 * @param	string	$password
	 * @return	string
	 */
	public function EncryptPassword($username, $password)
	{
		$password = self::$obj_functions->super_crypt($username, $password, SALT);

		unset($username);
		return $password;
	}

	/**
	 * Возвращает ID посетителя
	 *
	 * @return	int
	 */
	public function getUserID()
	{
		return (int)$this->arr_user['user_id'];
	}

	/**
	 * Возвращает UIN
	 *
	 * @return	string
	 */
	public function getUIN()
	{
		return $this->uin;
	}

	/**
	 * Возвращает "username" посетителя
	 *
	 * @return	string
	 */
	public function getUserName()
	{
		return $this->arr_user['username'];
	}

	/**
	 * Возвращает E-mail посетителя
	 *
	 * @return	string
	 */
	public function getUserEmail()
	{
		return $this->arr_user['email'];
	}

	/**
	 * Возвращает имя посетителя
	 *
	 * @return	string
	 */
	public function getUserFirstName()
	{
		return $this->arr_user['first_name'];
	}

	/**
	 * Возвращает фамилию посетителя
	 *
	 * @return	string
	 */
	public function getUserLastName()
	{
		return $this->arr_user['last_name'];
	}

	/**
	 * Возвращает аватар посетителя
	 *
	 * @return	string
	 */
	public function getUserAvatar()
	{
		return $this->arr_user['avatar'];
	}
	
	/**
	 * Бозвращает 1 если юзер администратор
	 */
	public function isAdmin()
	{
		return (int)$this->arr_user['is_admin'] > 0 ? true : false;
	}

	/**
	 * Проверяет существует ли в БД юзер по указанному E-mail,
	 * генерирует и записывает в поле "password_reset_code" уникальный код
	 * с помощью которогу юзер сможет сбросить старый пароль и ввести новый
	 * 
	 * @param	string	$email
	 * @param	string	$lang
	 * @return	bool
	 */
	public function forgotPassword($email, $lang)
	{
		//
		$status = false; 
		
		//
		if (trim($email) != '')
		{
			$sql = "SELECT
						user_id,
						email,
						password,
						first_name,
						last_name 
					FROM
						" . TABLE_PREFIX . "users
					WHERE
						email = " . self::$obj_functions->toMySQL($email) . " 
					LIMIT 1";
			
			//self::$obj_error->showMessage($sql, 3);
			$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
			if (self::$obj_db->sql_numrows($result) > 0)
			{
				$row = self::$obj_db->sql_fetchrow($result);
				
				// Сгенерируем уникальный код и запишем его в поле "password_reset_code"
				$password_reset_code = md5(self::$obj_functions->UIN()) . md5(self::$obj_functions->UIN());
				
				$sql = "UPDATE
							" . TABLE_PREFIX . "users
						SET
							password_reset_code = " . self::$obj_functions->toMySQL($password_reset_code) . "
						WHERE
							user_id = " . (int)$row['user_id'] . "
						LIMIT 1";
				
				//self::$obj_error->showMessage($sql, 3);
				$result1 = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
				
				//**************************************************************
				// Mailer
				//**************************************************************
				$strHTML = 'Confirmation Code: ' . $password_reset_code . '<br />';
				$strHTML.= '<a href="' . SITE_ROOT . LANG . '/reset-password/?code=' . $password_reset_code . '">Click here</a> to reset your password.';
				
				$strText = 'Confirmation Code: ' . $password_reset_code;

				$path = ABSPATH . 'templates/' . TPL_NAME . '/' . $lang . '/mail/';

				self::$obj_mailer->from = MAIL_FROM;
				self::$obj_mailer->to = self::$obj_functions->toHTML($row['email']);
				self::$obj_mailer->cc = MAIL_CC;
				self::$obj_mailer->subject = 'Password reset code';
				self::$obj_mailer->text = $strText;
				self::$obj_mailer->html = $strHTML;
				self::$obj_mailer->SetTemplate($path . 'mail.tpl');

				self::$obj_mailer->Send();
				//**************************************************************
				
				//
				$status = true;
			}

			self::$obj_db->sql_freeresult($result);
			self::$obj_db->sql_freeresult($result1);
			unset($result, $result1, $row, $password_reset_code, $sql, $email, $lang, $strHTML, $strText, $path);
		}
		
		return $status;
	}
	
	/**
	 * Проверяет свободно ли указанное имя пользователя
	 * 
	 * @param	string	$username
	 * @return	bool
	 */
	public function isUsernameFree($username)
	{
		//
		$is_free = false;
		
		//
		$sql = "SELECT
					count(*) AS qty
				FROM
					" . TABLE_PREFIX . "users
				WHERE
					username = " . self::$obj_functions->toMySQL($username) . "";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if (self::$obj_db->sql_numrows($result) > 0)
		{
			$row = self::$obj_db->sql_fetchrow($result);
			
			if ((int)$row['qty'] == 0)
			{
				// Не найдено имя юзера
				$is_free = true;
			}
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($username, $result, $row, $sql);
		
		return $is_free;
	}
	
	/**
	 * Проверяет свободен ли указанный Email
	 * 
	 * @param	string	$email
	 * @return	bool
	 */
	public function isEmailFree($email)
	{
		//
		$is_free = false;
		
		//
		$sql = "SELECT
					count(*) AS qty
				FROM
					" . TABLE_PREFIX . "users
				WHERE
					email = " . self::$obj_functions->toMySQL($email) . "";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if (self::$obj_db->sql_numrows($result) > 0)
		{
			$row = self::$obj_db->sql_fetchrow($result);
			
			if ((int)$row['qty'] == 0)
			{
				// Не найден
				$is_free = true;
			}
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($email, $result, $row, $sql);
		
		return $is_free;
	}

	/**
	 * Проверяет существует ли указанный код для смены пароля
	 * 
	 * @param	string	$code
	 * @return	bool
	 */
	public function isPasswordResetCodeValid($code)
	{
		//
		$is_valid = false;
		
		//
		$sql = "SELECT
					count(*) AS qty
				FROM
					" . TABLE_PREFIX . "users
				WHERE
					password_reset_code = " . self::$obj_functions->toMySQL($code) . "";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if (self::$obj_db->sql_numrows($result) > 0)
		{
			$row = self::$obj_db->sql_fetchrow($result);
			
			if ((int)$row['qty'] > 0)
			{
				$is_valid = true;
			}
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($code, $result, $row, $sql);
		
		return $is_valid;
	}
	
	/**
	 * Проверяет пароль юзера (соответствует ли указанному)
	 * 
	 * @param	string	$password
	 * @return	bool
	 */
	public function VerifyUserPassword($password)
	{
		//
		$is_valid = false;
		
		// Получим пароль в том виде, в каком он хранится в БД
		$password = self::$obj_functions->super_crypt($this->getUserName(), $password, SALT);

		$sql = "SELECT 
					user_id 
				FROM 
					" . TABLE_PREFIX . "users 
				WHERE 
					username = " . self::$obj_functions->toMySQL($this->getUserName(), true) . "
					AND
					password = " . self::$obj_functions->toMySQL($password, true) . "
				LIMIT 1";

		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if ( self::$obj_db->sql_numrows($result) > 0 )
		{
			// Юзер с указанным именем и паролем найден
			$is_valid = true;
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($password, $result, $row, $sql);
		
		return $is_valid;
	}
	
	/**
	 * Возвращает информацию о пользователе по указанному коду сброса пароля
	 * 
	 * @param	string	$code 
	 * @return	array
	 */
	public function getUserByResetCode($code)
	{
		$user = array();
		
		//
		$sql = "SELECT
					user_id, 
					username 
				FROM
					" . TABLE_PREFIX . "users
				WHERE
					password_reset_code = " . self::$obj_functions->toMySQL($code) . " 
				LIMIT 1";
		
		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if (self::$obj_db->sql_numrows($result) > 0)
		{
			$row = self::$obj_db->sql_fetchrow($result);
			
			$user['user_id'] = (int)$row['user_id'];
			$user['username'] = self::$obj_functions->toHTML($row['username']);
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($code, $result, $row, $sql);
		
		return $user;
	}
	
	/**
	 * Возвращает информацию о пользователе по указанному ID
	 * 
	 * @param	int		$user_id
	 * @return	array
	 */
	public function getUserByID($user_id)
	{
		$user = array();
		
		//
		$sql = "SELECT
					user_id, 
					username, 
					email 
				FROM
					" . TABLE_PREFIX . "users
				WHERE
					user_id = " . (int)$user_id . " 
				LIMIT 1";
		
		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		if (self::$obj_db->sql_numrows($result) > 0)
		{
			$row = self::$obj_db->sql_fetchrow($result);
			
			$user['user_id'] = (int)$row['user_id'];
			$user['username'] = self::$obj_functions->toHTML($row['username']);
			$user['email'] = self::$obj_functions->toHTML($row['email']);
		}
		
		self::$obj_db->sql_freeresult($result);
		unset($user_id, $result, $row, $sql);
		
		return $user;
	}
	
	/**
	 * Регистрация (добавление) нового пользователя
	 * 
	 * @param	string	$username
	 * @param	string	$password
	 * @param	string	$email
	 * @param	string	$first_name
	 * @param	string	$last_name
	 * @param	string	$avatar_file 
	 * @return	int		$user_id
	 */
	public function RegisterUser($username, $password, $email, $first_name, $last_name, $avatar_file)
	{
		//
		$user_id = 0;
		
		// Получим пароль в том виде, в каком он хранится в БД
		$password = self::$obj_functions->super_crypt(strtolower(trim($username)), trim($password), SALT);
		$token = md5(time() . trim($username) . $password);
		
		//
		$sql = "INSERT INTO " . TABLE_PREFIX . "users 
				(
					uin, 
					token,
					registration_date,
					lastvisit_date,
					username,
					password,
					email,
					email_confirmed,
					email_confirm_code,
					first_name,
					last_name,
					avatar 
				)
				VALUES
				(
					" . self::$obj_functions->toMySQL(self::$obj_functions->UIN()) . ",
					" . self::$obj_functions->toMySQL($token) . ",
					NOW(),
					NOW(),
					" . self::$obj_functions->toMySQL(trim($username)) . ",
					" . self::$obj_functions->toMySQL($password) . ",
					" . self::$obj_functions->toMySQL(trim($email)) . ",
					0,
					" . self::$obj_functions->toMySQL(self::$obj_functions->UIN()) . ",
					" . self::$obj_functions->toMySQL(trim($first_name)) . ",
					" . self::$obj_functions->toMySQL(trim($last_name)) . ",
					" . self::$obj_functions->toMySQL($avatar_file) . "
				)";
		
		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		$user_id = self::$obj_db->sql_nextid();
		
		self::$obj_db->sql_freeresult($result);
		unset($username, $password, $email, $first_name, $last_name, $avatar_file, $token, $sql, $result);
		
		//
		return $user_id;
	}
	
	/**
	 * Сохранение информации о пользователе
	 * 
	 * @param int		$user_id
	 * @param string	$email
	 * @param string	$first_name
	 * @param string	$last_name
	 * @param string	$sex
	 * @param string	$birthday
	 * @param string	$phone
	 * @param string	$fax
	 * @param string	$icq
	 * @param string	$msn
	 * @param string	$skype
	 * @param string	$languages 
	 */
	public function UpdateUserInfo($user_id, $email, $first_name, $last_name, $sex, $birthday, $phone, $fax, $icq, $msn, $skype, $languages)
	{
		$sql = "UPDATE 
					" . TABLE_PREFIX . "users 
				SET 
					email = " . self::$obj_functions->toMySQL(trim($email)) . ", 
					first_name = " . self::$obj_functions->toMySQL(trim($first_name)) . ", 
					last_name = " . self::$obj_functions->toMySQL(trim($last_name)) . ", 
					sex = " . self::$obj_functions->toMySQL(trim($sex)) . ", 
					birthday = " . self::$obj_functions->toMySQL($birthday) . ", 
					phone = " . self::$obj_functions->toMySQL(trim($phone)) . ", 
					fax = " . self::$obj_functions->toMySQL(trim($fax)) . ", 
					icq = " . self::$obj_functions->toMySQL(trim($icq)) . ", 
					msn = " . self::$obj_functions->toMySQL(trim($msn)) . ", 
					skype = " . self::$obj_functions->toMySQL(trim($skype)) . ", 
					languages = " . self::$obj_functions->toMySQL(trim($languages)) . " 
				WHERE 
					user_id = " . (int)$user_id . " 
				LIMIT 1";
		
		//self::$obj_error->showMessage($sql, 3);
		$result = self::$obj_db->sql_query($sql) or self::$obj_error->showMessageSQL(__FUNCTION__, basename(__FILE__), __LINE__);
		
		self::$obj_db->sql_freeresult($result);
		unset($user_id, $email, $first_name, $last_name, $sex, $birthday, $phone, $fax, $icq, $msn, $skype, $languages, $sql, $result);
	}
}
?>